#include "tcpwrapper.h"

#define USAGE "Usage: twitClient <CLIENT NAME> <SERVER ADDRESS> <SERVER PORT>\n"
#define OUT_RANGE "port number should be between 1024 and 65536\n"


void ReportError(string msg, bool IsExit)
{
	cout << "Error: "<< msg << endl;
	if (IsExit)
	{
		// close FDs
		exit(FAILURE);
	}
}
void handleArgs(int *port, string* address, string* cname, int argc, const char **argv)
{
	if (argc!=4) {
		cout << USAGE;
		exit(FAILURE);
	}
	*cname = argv[1];
	*address = argv[2];

	*port = atoi(argv[3]);
	/*  not needed
	if (*port < 1024 || *port >65536)
	{
		cout << OUT_RANGE;
		exit(FAILURE);
	}ServermainError(string msg, bool toDo)
	*/
	if (*port==0) // also if port was string
	{
		cout << "Illegal port number\n";
		exit(FAILURE);
	}
}

// will always beServerDis\n to the connection and not to stdIN
void sendMessage(int fd, string message)
{
    if (sendMsg(fd,message)==FAILURE)
    {
    	close(fd);
    	ReportError("Error sending to server",true);
    }
}

void handleUserInput(int fd, string msg)
{
	if (msg=="EXIT\n")
	{
		sendMessage(fd,"Dis\n");
		close(fd); // disconnect from server
		exit(SUCCESS);
	}
	sendMessage(fd,msg);  //simple
}

void handleServerInput(int fd, string msg)
{
	if (msg=="ServerDis\n")
	{
		cout << "The server EXITed properly\n";
		close(fd);
		exit(SUCCESS);
	}
	else if (msg=="ERROR failed to connect\n")
	{
		close(fd);
		exit(1);
	}
	else if (msg.substr(0,4)=="ERROR")
	{
		cerr << msg;
	}else{
		cout << msg;
	}
}

int main(int argc, const char **argv) {
	init_tcpwrapper(NULL);
	int port;
	string address;
	string cname;

	handleArgs(&port, &address, &cname, argc, argv);

	int connSocket = connect(port,address);
	sendMessage(connSocket, cname + "\n"); // Immediatly send the name of the client
    fd_set masterset;
    fd_set readfds;
    FD_ZERO(&masterset);
    FD_SET(connSocket, &masterset);
    FD_SET(STDIN_FILENO, &masterset);

    while(1)
    {
    	readfds = masterset; //copy the set again
    	//cout << "inserting to select" << endl;
    	if (select(connSocket+1, &readfds, NULL, NULL, NULL) == -1) //updating the set
    	{
    		ReportError("error select", true);
    	}

    	string msg;

    	if (FD_ISSET(connSocket, &readfds)) // the connection socket
    	{
    		//cout << "PASS select" << endl;
    		int res = recvMsg(connSocket, msg);
    		//cout << "PASS recieve" << endl;
    		if (res==FAILURE)
    		{
    			//cout << "BAAAAAAAAAA" << msg << endl;
    			// The server has disconnected
    			close(connSocket);
    			ReportError("The server disconnected", true);
    		} else {
    			//cout << "wanna print: " << msg << endl;
    			handleServerInput(connSocket,msg);
    		}

    	} else // user input
    	{
    		recvMsg(STDIN_FILENO, msg); // we dont care if this returns -1
    		handleUserInput(connSocket,msg);
    	}
    }
	return SUCCESS;
}
